<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Memory Leak Test</title>
    <link href="../css/pageStyle.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/js/all.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<h1>Memory Leak Test</h1>
<p>Open the browser's developer tools to monitor memory usage.</p>
<button id="startTest">Start Test</button>
<canvas id="testCanvas"></canvas>
<canvas id="memoryChart" width="800" height="400"></canvas>
<script type="module">
    import {Viewer, SceneModel} from "../../dist/xeokit-sdk.min.es.js";

    const iterations = 100; // Number of test loops
    const canvasId = "testCanvas";

    document.getElementById("startTest").addEventListener("click", async () => {
        console.log("Starting memory leak test...");

        const memoryUsage = [];
        let totalMemory = 0;

        for (let i = 0; i < iterations; i++) {
            console.log(`Iteration ${i + 1}/${iterations}`);

            // Step 1: Create Viewer
            const viewer = new Viewer({
                canvasId: canvasId,
                transparent: true
            });

            // Step 2: Load a model
            const sceneModel = new SceneModel(viewer.scene, {
                id: "testModel",
                position: [0, 0, 0],
                scale: [1, 1, 1],
                rotation: [0, 0, 0]
            });

            sceneModel.createGeometry({
                id: "testGeometry",
                primitive: "triangles",
                positions: [
                    1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1,
                    -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1,
                    -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1
                ],
                indices: [
                    0, 1, 2, 0, 2, 3,            // front
                    4, 5, 6, 4, 6, 7,            // right
                    8, 9, 10, 8, 10, 11,         // top
                    12, 13, 14, 12, 14, 15,      // left
                    16, 17, 18, 16, 18, 19,      // bottom
                    20, 21, 22, 20, 22, 23
                ]
            });

            sceneModel.createMesh({
                id: "testMesh",
                geometryId: "testGeometry",
                position: [0, 0, 0],
                scale: [1, 1, 1],
                rotation: [0, 0, 0],
                color: [1, 0, 0]
            });

            sceneModel.createEntity({
                id: "testEntity",
                meshIds: ["testMesh"],
                isObject: true
            });

            sceneModel.finalize();

            // Step 3: Unload the model
            sceneModel.destroy();

            // Step 4: Destroy the Viewer
            viewer.destroy();

            // Log memory usage after iteration
            if (window.performance && window.performance.memory) {
                const afterMemory = window.performance.memory.usedJSHeapSize / 1024 / 1024;
                memoryUsage.push(afterMemory);
                totalMemory += afterMemory;
            }

            // Allow some time for garbage collection
            await new Promise(resolve => setTimeout(resolve, 100));
        }

        // Calculate statistics
        const minMemory = Math.min(...memoryUsage);
        const maxMemory = Math.max(...memoryUsage);
        const avgMemory = totalMemory / memoryUsage.length;

        // Display statistics
        const statsDiv = document.createElement("div");
        statsDiv.innerHTML = `
            <h2>Memory Usage Statistics</h2>
            <p>Minimum Memory Usage: ${minMemory.toFixed(2)} MB</p>
            <p>Maximum Memory Usage: ${maxMemory.toFixed(2)} MB</p>
            <p>Average Memory Usage: ${avgMemory.toFixed(2)} MB</p>
        `;
        document.body.appendChild(statsDiv);

        // Visualize memory usage
        const ctx = document.getElementById("memoryChart").getContext("2d");
        new Chart(ctx, {
            type: "line",
            data: {
                labels: memoryUsage.map((_, index) => `Iteration ${index + 1}`),
                datasets: [
                    {
                        label: "Memory Usage (MB)",
                        data: memoryUsage,
                        borderColor: "rgba(75, 192, 192, 1)",
                        backgroundColor: "rgba(75, 192, 192, 0.2)",
                        borderWidth: 2,
                        fill: true
                    },
                    {
                        label: "Average Memory Usage (MB)",
                        data: Array(memoryUsage.length).fill(avgMemory),
                        borderColor: "rgba(255, 99, 132, 1)",
                        borderWidth: 2,
                        borderDash: [5, 5],
                        fill: false
                    }
                ]
            },
            options: {
                responsive: true,
                plugins: {
                    legend: {
                        display: true
                    }
                },
                scales: {
                    x: {
                        title: {
                            display: true,
                            text: "Iterations"
                        }
                    },
                    y: {
                        title: {
                            display: true,
                            text: "Memory Usage (MB)"
                        },
                        beginAtZero: true
                    }
                }
            }
        });
    });
</script>
</body>
</html>